﻿using System;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows;
using System.Collections;
using System.Windows.Media;
using System.Windows.Input;
using System.Threading;

namespace WPFTurnBasedStrategyGame
{    
    public class Gametangle : StackPanel
    {
        private Rect r;
        private RectangleGeometry rg;
        private LandType t;
        private string textOne, textTwo;
        Pen blackPen = new Pen(Brushes.Black, 1);
        Pen redPen = new Pen(Brushes.Red, 1);
        Pen grayPen = new Pen(Brushes.Gray, 1);
        Pen bluePen = new Pen(Brushes.Blue, 1);
        Typeface typeFace = new Typeface("Courier");
        private int x;
        private int y;
        private List<Piece> pieces;

        public static readonly RoutedEvent AddedToPathEvent = EventManager.RegisterRoutedEvent(
        "Pathed", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Gametangle));

        public Gametangle()
            : base()
        {
            Point p = new Point(0, 0);
            Size s = new Size(40, 40);
            r = new Rect(p, s);
            rg = new RectangleGeometry(r);
            this.Height = 40;
            this.Width = 40;
            this.MouseLeftButtonDown += new MouseButtonEventHandler(Gametangle_MouseLeftButtonDown);
            this.MouseEnter += new MouseEventHandler(Gametangle_MouseEnter);
            pieces = new List<Piece>();
        }

        void Gametangle_MouseEnter(object sender, MouseEventArgs e)
        {
            if (recordingMoves)
            {
                oldBackground = Background;
                Background = Brushes.Yellow;
                RaiseAddedToPathEvent();
            }
        }

        void RaiseAddedToPathEvent()
        {
            RoutedEventArgs newEventArgs = new RoutedEventArgs(Gametangle.AddedToPathEvent);
            RaiseEvent(newEventArgs);
        }

        public event RoutedEventHandler Pathed
        {
            add { AddHandler(AddedToPathEvent, value); }
            remove { RemoveHandler(AddedToPathEvent, value); }
        }

        void Gametangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //int a = 3;
        }


        public string Content
        {
            get
            {
                return "";
            }
            set
            {
                value = "";
            }
        }

        public List<Piece> GetPieces(GameTeam gt)
        {
            List<Piece> returnPieces = new List<Piece>();

            foreach (Piece p in pieces)
            {
                if (p.Team == gt)
                {
                    returnPieces.Add(p);
                }
            }

            return returnPieces;
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);

            drawingContext.DrawLine(blackPen, new Point(0, 0), new Point(40, 0));
            drawingContext.DrawLine(blackPen, new Point(40, 0), new Point(40, 40));
            drawingContext.DrawLine(blackPen, new Point(40, 40), new Point(0, 40));
            drawingContext.DrawLine(blackPen, new Point(0, 40), new Point(0, 0));

            if (textOne != null)
            {
                FormattedText formattedText = new FormattedText(textOne, Thread.CurrentThread.CurrentUICulture, FlowDirection.LeftToRight, typeFace, 12, Brushes.Black);
                drawingContext.DrawText(formattedText, new Point(5, 10));
            }

            if (textTwo != null)
            {
                FormattedText formattedText = new FormattedText(textTwo, Thread.CurrentThread.CurrentUICulture, FlowDirection.LeftToRight, typeFace, 12, Brushes.Black);
                drawingContext.DrawText(formattedText, new Point(5, 20));
            }

            if (t == LandType.City)
            {
                drawingContext.DrawLine(blackPen, new Point(10, 0), new Point(10, 40));
                drawingContext.DrawLine(blackPen, new Point(20, 0), new Point(20, 40));
                drawingContext.DrawLine(blackPen, new Point(30, 0), new Point(30, 40));

                drawingContext.DrawLine(blackPen, new Point(0, 10), new Point(40, 10));
                drawingContext.DrawLine(blackPen, new Point(0, 20), new Point(40, 20));
                drawingContext.DrawLine(blackPen, new Point(0, 30), new Point(40, 30));
            }
            else if (t == LandType.Mountain)
            {
                drawingContext.DrawLine(blackPen, new Point(20, 5), new Point(35, 35));
                drawingContext.DrawLine(blackPen, new Point(35, 35), new Point(5, 35));
                drawingContext.DrawLine(blackPen, new Point(5, 35), new Point(20, 5));
            }

            foreach (UIElement o in this.Children)
            {
                if (o is BorderFeature)
                {
                    HandleBorderFeature((BorderFeature)o, drawingContext);
                }
            }
        }

        private void HandleBorderFeature(BorderFeature bf, DrawingContext drawingContext)
        {
            if (bf.Feature == BorderFeatureType.Beach)
            {
                if (bf.Direction == BorderFeatureDirection.West)
                {
                    drawingContext.DrawRectangle(Brushes.Gray, grayPen, new Rect(new Point(0, 0), new Point(10, 40)));
                }
                else if (bf.Direction == BorderFeatureDirection.East)
                {
                    drawingContext.DrawRectangle(Brushes.Gray, grayPen, new Rect(new Point(30, 0), new Point(40, 40)));
                }
            }
            else if (bf.Feature == BorderFeatureType.River)
            {
                if (bf.Direction == BorderFeatureDirection.East)
                {
                    drawingContext.DrawRectangle(Brushes.Blue, bluePen, new Rect(new Point(37, 0), new Point(40, 40)));
                }
                else if (bf.Direction == BorderFeatureDirection.West)
                {
                    drawingContext.DrawRectangle(Brushes.Blue, bluePen, new Rect(new Point(0, 0), new Point(3, 40)));
                }
                else if (bf.Direction == BorderFeatureDirection.South)
                {
                    drawingContext.DrawRectangle(Brushes.Blue, bluePen, new Rect(new Point(0, 37), new Point(40, 40)));
                }
                else if (bf.Direction == BorderFeatureDirection.North)
                {
                    drawingContext.DrawRectangle(Brushes.Blue, bluePen, new Rect(new Point(0, 0), new Point(40, 3)));
                }
            }
            else if (bf.Feature == BorderFeatureType.Road)
            {
                if (bf.Direction == BorderFeatureDirection.North)
                {
                    drawingContext.DrawLine(redPen, new Point(20, 20), new Point(20, 0));
                }
                else if (bf.Direction == BorderFeatureDirection.East)
                {
                    drawingContext.DrawLine(redPen, new Point(20, 20), new Point(40, 20));
                }
                else if (bf.Direction == BorderFeatureDirection.West)
                {
                    drawingContext.DrawLine(redPen, new Point(20, 20), new Point(0, 20));
                }
                else if (bf.Direction == BorderFeatureDirection.South)
                {
                    drawingContext.DrawLine(redPen, new Point(20, 20), new Point(20, 40));
                }
                else if (bf.Direction == BorderFeatureDirection.SouthEast)
                {
                    drawingContext.DrawLine(redPen, new Point(20, 20), new Point(40, 40));
                }
                else if (bf.Direction == BorderFeatureDirection.NorthWest)
                {
                    drawingContext.DrawLine(redPen, new Point(20, 20), new Point(0, 0));
                }
            }
            else if (bf.Feature == BorderFeatureType.Bivouac)
            {
                if (bf.Direction == BorderFeatureDirection.North)
                {
                    drawingContext.DrawLine(blackPen, new Point(2, 2), new Point(7, 2));
                    drawingContext.DrawLine(blackPen, new Point(12, 2), new Point(17, 2));
                    drawingContext.DrawLine(blackPen, new Point(22, 2), new Point(27, 2));
                    drawingContext.DrawLine(blackPen, new Point(32, 2), new Point(37, 2));
                }
                else if (bf.Direction == BorderFeatureDirection.East)
                {
                    drawingContext.DrawLine(blackPen, new Point(37, 2), new Point(37, 7));
                    drawingContext.DrawLine(blackPen, new Point(37, 12), new Point(37, 17));
                    drawingContext.DrawLine(blackPen, new Point(37, 22), new Point(37, 27));
                    drawingContext.DrawLine(blackPen, new Point(37, 32), new Point(37, 37));
                }
                else if (bf.Direction == BorderFeatureDirection.South)
                {
                    drawingContext.DrawLine(blackPen, new Point(2, 37), new Point(7, 37));
                    drawingContext.DrawLine(blackPen, new Point(12, 37), new Point(17, 37));
                    drawingContext.DrawLine(blackPen, new Point(22, 37), new Point(27, 37));
                    drawingContext.DrawLine(blackPen, new Point(32, 37), new Point(37, 37));
                }
                else if (bf.Direction == BorderFeatureDirection.West)
                {
                    drawingContext.DrawLine(blackPen, new Point(2, 2), new Point(2, 7));
                    drawingContext.DrawLine(blackPen, new Point(2, 12), new Point(2, 17));
                    drawingContext.DrawLine(blackPen, new Point(2, 22), new Point(2, 27));
                    drawingContext.DrawLine(blackPen, new Point(2, 32), new Point(2, 37));
                }
            }
            else if (bf.Feature == BorderFeatureType.Frontier)
            {
                if (bf.Direction == BorderFeatureDirection.East)
                {
                    drawingContext.DrawRectangle(Brushes.Red, redPen, new Rect(new Point(37, 2), new Point(40, 7)));
                    drawingContext.DrawRectangle(Brushes.Red, redPen, new Rect(new Point(37, 12), new Point(40, 17)));
                    drawingContext.DrawRectangle(Brushes.Red, redPen, new Rect(new Point(37, 22), new Point(40, 27)));
                    drawingContext.DrawRectangle(Brushes.Red, redPen, new Rect(new Point(37, 32), new Point(40, 37)));
                }
                else if (bf.Direction == BorderFeatureDirection.West)
                {
                    drawingContext.DrawRectangle(Brushes.Red, redPen, new Rect(new Point(0, 2), new Point(2, 7)));
                    drawingContext.DrawRectangle(Brushes.Red, redPen, new Rect(new Point(0, 12), new Point(2, 17)));
                    drawingContext.DrawRectangle(Brushes.Red, redPen, new Rect(new Point(0, 22), new Point(2, 27)));
                    drawingContext.DrawRectangle(Brushes.Red, redPen, new Rect(new Point(0, 32), new Point(2, 37)));
                }
            }
        }

        public LandType Terrain
        {
            set
            {
                t = value;
                switch (t)
                {
                    case LandType.Ocean:
                        Background = Brushes.Blue;
                        break;
                    case LandType.Land:
                    case LandType.City:
                    case LandType.Mountain:
                        Background = Brushes.White;
                        break;
                    case LandType.Forest:
                        Background = Brushes.Green;
                        break;
                }
            }
            get
            {
                return t;
            }
        }

        public string TextOne
        {
            set
            {
                textOne = value;
            }
            get
            {
                return textOne;
            }
        }

        public string TextTwo
        {
            set
            {
                textTwo = value;
            }
            get
            {
                return textTwo;
            }
        }        

        private bool recordingMoves;
        private Brush oldBackground;

        internal void ToggleRecordingMoves()
        {
            recordingMoves = !recordingMoves;
            if (!recordingMoves && oldBackground != null)
            {
                ResetBackground();
            }
        }

        internal void ResetBackground()
        {
            Background = oldBackground;
        }

        internal bool HasFeatureInThisDirection(BorderFeatureDirection bfd, BorderFeatureType bft)
        {
            foreach (UIElement o in this.Children)
            {
                if (o is BorderFeature)
                {
                    BorderFeature bf = (BorderFeature)o;
                    if (bf.Feature == bft && bf.Direction == bfd)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        internal void CancelMove()
        {
            Background = oldBackground;
        }

        public int X
        {
            get
            {
                return x;
            }
            set
            {
                x = value;
            }
        }

        public int Y
        {
            get
            {
                return y;
            }
            set
            {
                y = value;
            }
        }

        public List<Piece> Pieces
        {
            get
            {
                return pieces;
            }
            set
            {
                pieces = value;
            }
        }


        internal IEnumerable<Piece> GetEnemyPieces(GameTeam gameTeam)
        {
            List<Piece> lp = new List<Piece>();   
        
            GameTeam gt;

            if (gameTeam == GameTeam.Blue)
            {
                gt = GameTeam.Red;
            }
            else
            {
                gt = GameTeam.Blue;
            }

            foreach (Piece p in Pieces)
            {
                if (p.Team == gt)
                {
                    lp.Add(p);
                }
            }

            return lp;
        }
    }
}
